//////////////////////////////////////////////////////////////////////////
// $Id: Target.cpp,v 1.1 2009/04/03 12:46:11 sunjun Exp $
//////////////////////////////////////////////////////////////////////////

#include "Local.h"

//////////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////////

NAMESPACE_BEGIN

//////////////////////////////////////////////////////////////////////////	

	Target::Target()
	{
		
	}

	Target::~Target() 
	{
		
	}

	//////////////////////////////////////////////////////////////////////////	

	/*
	====================
	setRenderTexture
	====================
	*/
	INLINE VOID Target::setRenderTexture( const RenderTexture * texture, U32 face )
	{
		CHECK(texture&&mRTs.size()<=gD3DCAPS9.NumSimultaneousRTs&&face<6);
		mRTs.push_back(std::pair<RenderTexturePtr,U32>((RenderTexture*)texture,face));
	}

	/*
	====================
	setDepthSurface
	====================
	*/
	INLINE VOID Target::setDepthSurface( const DepthSurface * surface )
	{
		CHECK(surface);
		mDSPtr = (DepthSurface*)surface;
	}

	/*
	====================
	operator
	====================
	*/
	INLINE VOID Target::operator() (Context*rc)
	{
		GUARD(Target::operator());

		CHECK(rc);

		HRESULT hr;		

		// set the render target
		U32 count = mRTs.size();
		if(count > 0)
		{
			for( U32 i = 0; i < count; i++ )
			{
				CHECK( mRTs[i].first->mRCPtr == rc );
				hr = ((IDirect3DDevice9*)rc->handle())->SetRenderTarget( i, (IDirect3DSurface9*)mRTs[i].first->mSHandle[mRTs[i].second] );
				if(FAILED(hr)) MAssert(VA("Target::operator() : fail to set the render target(%s)!", DXGetErrorDescription(hr)));
			}
		}
		else
		{
			// restore the old render target 0 (back buffer)
			for( U32 i = 0; i < gD3DCAPS9.NumSimultaneousRTs; i++ )
			{
				if( i == 0 )
				{
					hr = ((IDirect3DDevice9*)rc->handle())->SetRenderTarget(0, (IDirect3DSurface9*)rc->mCRT);
				}
				else
				{
					hr = ((IDirect3DDevice9*)rc->handle())->SetRenderTarget(i, NULL);
				}
				if(FAILED(hr)) MAssert(VA("Target::operator() : fail to set the default render target(%s)!", DXGetErrorDescription(hr)));
			}
		}

		// set the depth stencil surface		
		if(mDSPtr)
		{
			CHECK(mDSPtr->mRCPtr == rc);
			hr = ((IDirect3DDevice9*)rc->handle())->SetDepthStencilSurface((IDirect3DSurface9*)mDSPtr->mHandle);
			if(FAILED(hr)) MAssert(VA("Target::operator() : fail to set the depth stencil surface(%s)!", DXGetErrorDescription(hr)));
		}
		else
		{
			// restore the old depth stencil surface (back buffer)
			hr = ((IDirect3DDevice9*)rc->handle())->SetDepthStencilSurface((IDirect3DSurface9*)rc->mDRT);
			if(FAILED(hr)) MAssert(VA("Target::operator() : fail to set the default depth stencil surface(%s)!", DXGetErrorDescription(hr)));
		}

		UNGUARD;
	}
	

//////////////////////////////////////////////////////////////////////////

NAMESPACE_END

//////////////////////////////////////////////////////////////////////////
